Part One -- Getting there.
by NymSandra
Originally this job was called "fool" because a wise
person should never speak about what they know. The reason for that is very
simple; once you tell about what you know or think is important to others,
someone will come along and tell you it's not or will ask about those things
which you've left out. The same it seems applies to such routine items as the
various modes of basic VGA cards under the mode 13h category. Therefore I have
decided to break up the mode 13h tutors into separate topics, each one covering
a single aspect. So hang on, here we go into the mode 13h form of display...
Mode 13h
Oddly enough, most VGA card and monitor combinations can
perform a wide variety of different displays, BIOS itself offering us only one
out of the total collection. Most of these modes are often referred to by the
term 13x or 13hx, but are in fact a group of planar video modes that require
special routines to get into and operate properly. A very great deal has been
written about them before.
The three most common variants, and the subject of the
last version of this tutor, are the 320 by 200, the 320 by 240, and the 360 by
480 pixel wide and high screens, all with 256 possible colors. Often times you
will find these major versions called modes X, Y and Z, but there is also a well
known confusion between these labels. Therefore, if you ever need help in any of
these modes, it is suggested you say simply mode X and then state the actual
dimensions of your screen for clarity. (My own reference book for example refers
to the 320 by 240 mode as mode X, while the 320 by 200 is called mode Y, and the
360 by 480 as mode Z. Still other texts use different meanings, the most
commonly switched are the X and the Y by definition.)
However, all of these modes operate in essentially the
same way, because each changes key control registers inside the VGA card. Quite
a few combinations are possible and used for various purposes. The basic range
of possible video modes are;
320x200 (basic mode 13h)
320x175 360x175
320x200 X 360x200
320x240 Y 360x240
320x350 360x350
320x400 360x400
320x480 360x480 Z
All of these video modes operate with the colors
available from the pallet and, with the exception of the basic mode 13h, four
pixel planes worth of data across the screen line. If you've never dealt with
pixel planes before they are really quite easy, each point of color across the
video line hangs upon another block of memory assigned to the video space. This
means that pixel 0,0 is on plane 1, pixel 1,0 is on plane 2, etc. Like this;
The VGA card itself reads these planes in rapid
succession, plane 1 then 2, 3 and 4 and back to plane 1. What you see across the
screen is the result of the interlace, so how we address each pixel is done
through another register in the card; the Plane Mask Register which selects
where our data will come and go. But we'll get to that in a moment, let's first
see how we go about setting up these various modes.
All of these video modes are well dated by now, the SVGA
card and VESA having taken over the scene. But when you are learning they serve
a useful purpose, getting your mind used to thinking in graphics and shaking out
the bugs in your idea. So we'll start with the easiest first, then going on to
the more complex ones:
Starting A Mode
As said before the basis of all these modes is to modify
the video controller's registers, changing the values to something other than
BIOS puts there. Since there are some 60 registers that must be programmed for
most any video mode, it is most common to use BIOS to set a mode close to the
one desired and then change only those registers that need to be modified for
the desired display. All of these modes are variants of the BIOS one, so we make
a call to the BIOS 10 hex interrupt with a 13 hex in the AX register, as shown
below in assembly language;
This sets up the screen to a 320 pixel by 200 line mode,
with 256 colors available from the palette. However this is the standard mode,
which is commonly used because the screen forms exactly one segment available to
the CPU. It is therefor rather simple to use and is relatively fast because
there is no messing about with the controller registers or pixel planes, so it
remains fairly popular. It does not however support multiple pages, nor can be
used with fast paste or other screen trickery.
In the constant quest for good, clean, smooth and fast
looking graphics and animations, several programmers stumbled upon the extended
modes X, Y and Z. Most of these modes combine the timings of 13h and other
screen modes, the details of which you can find in the book, "Programmers guide
to the EGA/VGA" by Richard F. Ferraro. (ISBN 0-201-57025-4) For reasons of
clarity I will address the X mode first, which I suspect that my book mistakenly
calls mode Y. I refer to the planar version of the 320 by 200 pixel mode set by
BIOS.
Getting into this first extended mode is really the
easiest of the group, for it requires that we modify only four registers. It
does however introduce a new item into our code, that bit plane register for
every pixel plotted. You see, most cards today have more memory than a single
segment, set into a line very much like the main RAM inside the computer. The
trouble is, according to the CPU the screen can only be in one segment at any
time, thus there is a conflict of interest going on. This means the video must
pull some fancy footwork to get all of it's memory into that one segment. This
is called Planar mode, meaning that one plane, or level of an image, can be
addressed by the CPU at any one time. The plane mask register controls this
value. In addition, we have to tell the card that we want it to do the footwork
for us, by setting the other registers to their proper values. Here's how;
It is common at this point to clear all the planes,
usually by writing some color into each of the pixels on the screen. This can be
achieved by the following code;
Now the screen is ready for use. However, finding any one
pixel is no longer that easy because each of these four planes overlap one
another. Remember that "enable all planes" command from up above? Well that "F"
part is the command itself. Since the "F" value in hex is the same as four
binary ones, this turns all planes on for reading the CPU data. It also means
that the first bank is enabled by a 1 in this place, the second with a 2, the
third a 4 (remember, we're talking bits here) and the last with an 8 in the
above command. With a bit of programming trickery we can easily reach any pixel,
such a sample of that code is presented below;
Why the times 80 in the middle? I hear you cry. Well, the
screen is 320 pixels wide and if you divide that by 4 you get 80 bytes per
screen line. That's how the banks work, interlacing each other as the video
scans left to right. Reading pixels has the same problem, though you have to
remember yet another register in order to do that. Like this;
Now we can get to the fun stuff, setting the other
variants of mode 13h.
Oddly enough, setting the other styles of mode 13h are
really quite similar, and based upon nearly the exact same code. In fact, with
the exception of but a few values the code is identical, making similar changes
to the registers with the same type of coding. So without any further
discussion, here's a sample of how to get into the 320 by 240 pixel mode;
This process changes the dot clock inside the card,
allowing it to display 240 lines in the vertical direction. This is rather a
handy mode in some cases, for it means that the pixels are nearly square and a
line stepping in both the X and Y directions appears as a 45 degree angle. It
also means that you have the "normal" number of pixels plus 40 more lines of
them at the bottom, which is handy for a split screen status display or other
use. It does however mean that your pixels aren't as tall as the previous two
modes, so you may have to readjust your sprites or other drawings. However, this
mode also means you can use the same plotting code as above, and you usually
have about 3 pages of screens available in memory for page flipping.
Staying with this same side of the modes I listed above,
(that is to say 320 pixels in the horizontal direction) we get to the next
variant, that of 320 by 175 lines. Again, this mode uses the exact same code,
but if you look closely you will see a change in the data. (Changes marked with
-->)
This piece of code and table will change the screen
timing in the vertical direction, essentially "cutting off" the screen at the
175th line. Further variants do the same, by again changing the clock and screen
definition values. I am not about to take you through them all, instead I offer
a piece of code that will perform this for you, at the bottom of this page.
As a final example I offer the original text of this
tutor page, that code for setting up the screen to the 360 by 480 mode with 256
colors. I myself prefer this mode for doing GUIs, but it is not very useful to
the game programmer not using a virtual screen away from the video card. The
reason is, you get exactly one page in this mode again, so page flipping is not
an option. However, you can still fast paste in this mode and you have a bit of
memory left over at the bottom of the card in which to make a "pool" of images.
(About 87k pixels, the screen takes 169k.) This screen mode is also handy when
you want to learn off-card buffering, so I include it for your reference. Here's
how to get into it;
As you can see, getting into all these modes is actually
very similar, only the data, clock and number of registers adjusted has changed.
Using this high density mode also means that your pixels will be very short,
with over twice as many in the vertical direction as is normal. Slope 1 lines
will appear slightly slanted other than 45 degrees, but it can be useful for
some things. Lastly, before we go on to the universal code, I'll drop off an
example of finding any pixel for the 360 wide modes;
Yes, it's the same code as before, only with an adjusted
multiplier value to equal 90 bytes per line. There are other ways of doing this,
some which lend themselves particularly well to SVGA modes and such, but this
works for these wide modes. Now on to the universal code;
Universal Mode Setting Code Example
I'm not sure where I picked this up precisely but it is
easy enough to use if you program in ASM.
If you program in a higher level like C or Pascal you
will need a bit of a driver to use it, mostly in saving those registers your
compiler requires to prevent it from getting lost. A simple call to this code
with the BX register loaded correctly will set any 13h mode you desire, and
after that you can work with the screen.
Remember; use the first version of Set_Pixel for any
variation of the 320 pixel wide modes, and the second version of Set_Pixel for
those with 360 pixels across the screen.
I hope this lays to rest any discussion about "forgotten"
video modes. (Nyah!)
See you on the channel!
Write Me
08/04/98

Prog Next
Go back
to home
page.
A special thank you goes to Kuwanger99, without whose insistent pestering of
me this page would not have been updated.
This page updated to correct a 320x200 error pointed out by Kaiju01 --
Thanks!